﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Элементы.КнопкаПерейтиКНастройкам.Видимость = Ложь;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда
		МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме");
		ИспользуютсяПрофилиБезопасности = МодульРаботаВБезопасномРежиме.ИспользуютсяПрофилиБезопасности();
	Иначе
		ИспользуютсяПрофилиБезопасности = Ложь;
	КонецЕсли;
	
	Если ИспользуютсяПрофилиБезопасности Тогда
		СпособНастройки = "Вручную";
	Иначе
		СпособНастройки = "Автоматически";
	КонецЕсли;
	
	ДоступноПолучениеПисем = РаботаСПочтовымиСообщениямиСлужебный.НастройкиПодсистемы().ДоступноПолучениеПисем;
	КонтекстныйРежим = Параметры.КонтекстныйРежим;
	Перенастройка = Параметры.Перенастройка;
	Элементы.ИспользоватьУчетнуюЗапись.Видимость = Не КонтекстныйРежим И ДоступноПолучениеПисем;
	Элементы.Протокол.Доступность = ДоступноПолучениеПисем;
	Элементы.ОставлятьПисьмаНаСервере.Видимость = ДоступноПолучениеПисем;
	
	Элементы.НастройкаУчетнойЗаписиЗаголовок.Заголовок = ?(КонтекстныйРежим,
		НСтр("ru = 'Для отправки писем настройте почту'"),
		НСтр("ru = 'Введите настройки почты'"));
		
	Элементы.НастройкаУчетнойЗаписиЗаголовок.Видимость = КонтекстныйРежим;
	Заголовок = НСтр("ru = 'Настройка почты'");
	
	ИспользоватьДляПолучения = Не КонтекстныйРежим И ДоступноПолучениеПисем;
	ИспользоватьДляОтправки = Истина;
	Элементы.Страницы.ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи;
	
	КлючСохраненияПоложенияОкна = ?(КонтекстныйРежим, "КонтекстныйРежим", "НеконтекстныйРежим");
	
	СпособАутентификации = "Пароль";
	
	Если Параметры.Свойство("Ключ") Тогда
		УчетнаяЗаписьСсылка = Параметры.Ключ;
		ЗаполнитьСвойстваУчетнойЗаписи();
	Иначе
		СсылкаНовойУчетнойЗаписи = Справочники.УчетныеЗаписиЭлектроннойПочты.ПолучитьСсылку();
		
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
			МодульУправлениеКонтактнойИнформацией = ОбщегоНазначения.ОбщийМодуль("УправлениеКонтактнойИнформацией");
			КонтактнаяИнформацияОбъекта = МодульУправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
				Пользователи.ТекущийПользователь(), Перечисления["ТипыКонтактнойИнформации"].АдресЭлектроннойПочты, , Ложь);
			Для Каждого Контакт Из КонтактнаяИнформацияОбъекта Цикл
				Адрес = Контакт.Представление;
				Если Справочники.УчетныеЗаписиЭлектроннойПочты.НайтиПоРеквизиту("АдресЭлектроннойПочты", Адрес).Пустая() Тогда
					АдресЭлектроннойПочты = Адрес;
					ТекущийЭлемент = Элементы.Пароль;
					ИмяОтправителяПисем = Строка(Пользователи.ТекущийПользователь());
					Прервать;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
	
	Элементы.НеУдалосьПодключитьсяКартинкаИНадпись.Видимость = Ложь;
	Элементы.КнопкаНазад.Видимость = Ложь;
	
	ЭтоПолноправныйПользователь = Пользователи.ЭтоПолноправныйПользователь();
	Элементы.ДляКогоУчетнаяЗапись.Видимость = ЭтоПолноправныйПользователь И Не КонтекстныйРежим;
	ВидУчетнойЗаписи = ?(ЭтоПолноправныйПользователь, "Общая", "Персональная");
	Элементы.ИмяОтправителя.Видимость = Не КонтекстныйРежим;
	
	ТребуетсяАвторизацияПриОтправкеПисем = Истина;
	
	Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
		Элементы.Пароль.РастягиватьПоГоризонтали = Истина;
		Элементы.СпособАутентификации.Видимость = Истина;
		Элементы.СпособАутентификацииПароль.Видимость = Ложь;
		Элементы.СпособАутентификацииПочтовыйСервис.Видимость = Ложь;
		Элементы.ГруппаСпособАутентификацииПароль.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
		Элементы.Пароль.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Авто;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	ПодключитьОбработчикОжидания("НастроитьЭлементыТекущейСтраницыПриОткрытии", 0.1, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	
	Если Не ТребуетсяПодтверждениеЗакрытияФормы Тогда
		Возврат;
	КонецЕсли;
	
	Отказ = Истина;
	Если ЗавершениеРаботы Тогда
		Возврат;
	КонецЕсли;
	
	ПодключитьОбработчикОжидания("ПоказатьВопросПередЗакрытиемФормы", 0.1, Истина);
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ПарольПриИзменении(Элемент)
	ПарольДляОтправкиПисем = ПарольДляПолученияПисем;
КонецПроцедуры

&НаКлиенте
Процедура ОставлятьКопииПисемНаСервереПриИзменении(Элемент)
	ОбновитьДоступностьНастройкиДнейДоУдаления();
КонецПроцедуры

&НаКлиенте
Процедура УдалятьПисьмаССервераПриИзменении(Элемент)
	ОбновитьДоступностьНастройкиДнейДоУдаления();
КонецПроцедуры

&НаКлиенте
Процедура АдресЭлектроннойПочтыПриИзменении(Элемент)
	НастройкиЗаполнены = Ложь;
	ТребуетсяПодтверждениеЗакрытияФормы = Истина;
КонецПроцедуры

&НаКлиенте
Процедура ИмяОтправителяПисемПриИзменении(Элемент)
	ТребуетсяПодтверждениеЗакрытияФормы = Истина;
КонецПроцедуры

&НаКлиенте
Процедура ПротоколПриИзменении(Элемент)
	УстановитьВидимостьЭлементов();
	Элементы.СерверВходящейПочты.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Сервер %1'"), Протокол);
КонецПроцедуры

&НаКлиенте
Процедура ШифрованиеПриОтправкеПочтыПриИзменении(Элемент)
	ИспользоватьЗащищенноеСоединениеДляИсходящейПочты = ШифрованиеПриОтправкеПочты = "SSL";
КонецПроцедуры

&НаКлиенте
Процедура ШифрованиеПриПолученииПочтыПриИзменении(Элемент)
	ИспользоватьЗащищенноеСоединениеДляВходящейПочты = ШифрованиеПриПолученииПочты = "SSL";
КонецПроцедуры

&НаКлиенте
Процедура НужнаПомощьНажатие(Элемент)
	
	РаботаСПочтовымиСообщениямиКлиент.ПерейтиКДокументацииПоВводуУчетнойЗаписиЭлектроннойПочты();
	
КонецПроцедуры

&НаКлиенте
Процедура СообщенияОбОшибкахОткрытие(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Элементы.Страницы.ТекущаяСтраница = Элементы.ТехническиеПодробностиОшибки;
	НастроитьЭлементыТекущейСтраницы();
	
КонецПроцедуры

&НаКлиенте
Процедура ТекстТехническиеПодробностиОшибкиОткрытие(Элемент, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;
	Элементы.Страницы.ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи;
	НастроитьЭлементыТекущейСтраницы();
	
КонецПроцедуры

&НаКлиенте
Процедура СпособАутентификацииПриИзменении(Элемент)
	Элементы.Пароль.Доступность = СпособАутентификации = "Пароль";
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте

Процедура Далее(Команда)
	
	ПерейтиНаСледующуюСтраницу(Команда);
	
КонецПроцедуры

&НаКлиенте
Процедура Назад(Команда)
	
	ТекущаяСтраница = Элементы.Страницы.ТекущаяСтраница;
	
	ПредыдущаяСтраница = Неопределено;
	Если ТекущаяСтраница = Элементы.НастройкаСервераИсходящейПочты Тогда
		ПредыдущаяСтраница = Элементы.НастройкаУчетнойЗаписи;
	ИначеЕсли ТекущаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи Или ТекущаяСтраница = Элементы.ТехническиеПодробностиОшибки Тогда
		ПредыдущаяСтраница = Элементы.НастройкаУчетнойЗаписи;
	ИначеЕсли ТекущаяСтраница = Элементы.ПриПроверкеОбнаруженыОшибки Тогда
		ПредыдущаяСтраница = Элементы.НастройкиАвторизацииПриложения;
		ПроверкаЗавершиласьСОшибками = Ложь;
	КонецЕсли;
	
	Если ПредыдущаяСтраница <> Неопределено Тогда
		Элементы.Страницы.ТекущаяСтраница = ПредыдущаяСтраница;
	Иначе
		Элементы.Страницы.ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи;
	КонецЕсли;
	
	НастроитьЭлементыТекущейСтраницы()
КонецПроцедуры

&НаКлиенте
Процедура Отмена(Команда)
	ОтменитьВыполнениеЗадания(ИдентификаторЗадания);
	Закрыть(Ложь);
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Процедура ЗаполнитьСвойстваУчетнойЗаписи()
	ТекстЗапроса =
	"ВЫБРАТЬ
	|	УчетныеЗаписиЭлектроннойПочты.АдресЭлектроннойПочты КАК АдресЭлектроннойПочты,
	|	УчетныеЗаписиЭлектроннойПочты.ИмяПользователя КАК ИмяОтправителяПисем,
	|	УчетныеЗаписиЭлектроннойПочты.Наименование КАК НазваниеУчетнойЗаписи,
	|	УчетныеЗаписиЭлектроннойПочты.АвторизацияСПомощьюПочтовогоСервиса
	|ИЗ
	|	Справочник.УчетныеЗаписиЭлектроннойПочты КАК УчетныеЗаписиЭлектроннойПочты
	|ГДЕ
	|	УчетныеЗаписиЭлектроннойПочты.Ссылка = &Ссылка";
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("Ссылка", УчетнаяЗаписьСсылка);
	Выборка = Запрос.Выполнить().Выбрать();
	Если Не Выборка.Следующий() Тогда
		Возврат;
	КонецЕсли;

	ЗаполнитьЗначенияСвойств(ЭтотОбъект, Выборка);
	ТолькоАвторизация = Параметры.ТолькоАвторизация;
	Если Выборка.АвторизацияСПомощьюПочтовогоСервиса Или ТолькоАвторизация Тогда
		СпособАутентификации = "OAuth";
		Элементы.Пароль.Доступность = Ложь;
		Если ТолькоАвторизация Тогда
			НастройкиАвторизацииНаПочтовомСервере = НастройкиАвторизацииНаПочтовомСервере();
			НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
			
			Если ЗначениеЗаполнено(НастройкиАвторизации) И ЗначениеЗаполнено(НастройкиАвторизации.ИдентификаторПриложения) Тогда
				ИдентификаторПриложения = НастройкиАвторизации.ИдентификаторПриложения;
				АдресПеренаправления = НастройкиАвторизации.АдресПеренаправления;
				Если ЭтоВебКлиент() Тогда
					АдресПеренаправления = НастройкиАвторизации.АдресПеренаправленияВебКлиент;
				КонецЕсли;
				
				ПарольПриложения = НастройкиАвторизации.ПарольПриложения;
				Элементы.Страницы.ТекущаяСтраница = Элементы.Авторизация;
				
				Если ЭтоВебКлиент() Тогда
					Элементы.ВариантыАвторизации.ТекущаяСтраница = Элементы.БраузерОперационнойСистемы;
					ТекущийЭлемент = Элементы.ВебСтраница;
				Иначе
					Элементы.ВариантыАвторизации.ТекущаяСтраница = Элементы.ВстроенныйБраузер;
				КонецЕсли;
			Иначе
				Элементы.Страницы.ТекущаяСтраница = Элементы.НастройкиАвторизацииПриложения;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Элементы.АдресЭлектроннойПочты.ОтображениеПодсказки = 
		?(УчетнаяЗаписьСсылка = РаботаСПочтовымиСообщениями.СистемнаяУчетнаяЗапись(),
			ОтображениеПодсказки.ОтображатьСнизу, ОтображениеПодсказки.Нет);
		
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьВопросПередЗакрытиемФормы()
	ТекстВопроса = НСтр("ru = 'Введенные данные не записаны. Закрыть форму?'");
	ОписаниеОповещения = Новый ОписаниеОповещения("ЗакрытиеФормыПодтверждено", ЭтотОбъект);
	Кнопки = Новый СписокЗначений;
	Кнопки.Добавить("Закрыть", НСтр("ru = 'Закрыть'"));
	Кнопки.Добавить(КодВозвратаДиалога.Отмена, НСтр("ru = 'Не закрывать'"));
	ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, Кнопки, , КодВозвратаДиалога.Отмена, НСтр("ru = 'Настройка почты'"));
КонецПроцедуры

&НаКлиенте
Процедура ЗакрытиеФормыПодтверждено(РезультатВопроса, ДополнительныеПараметры = Неопределено) Экспорт
	
	Если РезультатВопроса = КодВозвратаДиалога.Отмена Тогда
		Возврат;
	КонецЕсли;
	
	ТребуетсяПодтверждениеЗакрытияФормы = Ложь;
	Закрыть(Ложь);
	
КонецПроцедуры

&НаКлиенте
Процедура ПерейтиНаСледующуюСтраницу(Команда = Неопределено)
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	Отказ = Ложь;
	ТекущаяСтраница = Элементы.Страницы.ТекущаяСтраница;
	
	СледующаяСтраница = Неопределено;
	Если ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи Или ТекущаяСтраница = Элементы.ТехническиеПодробностиОшибки Тогда
		ПроверитьЗаполнениеНаСтраницеНастройкаУчетнойЗаписи(Отказ);
		Если Не Отказ И Не НастройкиЗаполнены Тогда
			ЗаполнитьНастройкиУчетнойЗаписи();
		КонецЕсли;
		
		Если Не Отказ И СпособАутентификации = "OAuth" Тогда
			ПроверкаЗавершиласьСОшибками = Ложь;
			СледующаяСтраница = Элементы.НастройкиАвторизацииПриложения;
			
			НастройкиАвторизацииНаПочтовомСервере = НастройкиАвторизацииНаПочтовомСервере();
			НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
			
			Если ЗначениеЗаполнено(НастройкиАвторизации) Тогда
				Если ЗначениеЗаполнено(НастройкиАвторизации.АдресАвторизации) Тогда
					УстановитьТекстыПоясненийПоРегистрацииПриложения();
				КонецЕсли;
				ИдентификаторПриложения = НастройкиАвторизации.ИдентификаторПриложения;
				ПарольПриложения = НастройкиАвторизации.ПарольПриложения;
			КонецЕсли;
			
			Если Не ЗначениеЗаполнено(АдресПеренаправления) 
				Или ЗначениеЗаполнено(НастройкиАвторизации) И Не ЗначениеЗаполнено(НастройкиАвторизации.АдресАвторизации)
				Или ЭтоВебКлиент() И Не ДоступнаАвторизацияПоКоду() Тогда
				СообщенияОбОшибках = НСтр("ru = 'Не найдены настройки авторизации почтового сервиса. Используйте авторизацию по паролю.'");
				ПроверкаЗавершиласьСОшибками = Истина;
				СпособАутентификации = "Пароль";
				СледующаяСтраница = Элементы.НастройкаУчетнойЗаписи;
			ИначеЕсли ЗначениеЗаполнено(ИдентификаторПриложения) Тогда
				СледующаяСтраница = Элементы.Авторизация;
				ПодключитьОбработчикОжидания("АвторизоватьсяНаПочтовомСервере", 0.1, Истина);
			КонецЕсли;
		
		ИначеЕсли ПроверкаЗавершиласьСОшибками Тогда
			СледующаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи;
		ИначеЕсли Не Отказ Тогда
			Если СпособНастройки = "Автоматически" Тогда
				СледующаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи;
			Иначе
				Если ИспользоватьДляОтправки Или ИспользоватьДляПолучения Тогда
					СледующаяСтраница = Элементы.НастройкаСервераИсходящейПочты;
				Иначе
					СледующаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	ИначеЕсли ТекущаяСтраница = Элементы.НастройкиАвторизацииПриложения Тогда
		ПроверитьЗаполнениеНаСтраницеНастройкиАвторизацииПриложения(Отказ);
		Если Не Отказ Тогда
			Если ПроверкаЗавершиласьСОшибками Тогда
				СледующаяСтраница = Элементы.НастройкаУчетнойЗаписи;
			Иначе
				СледующаяСтраница = Элементы.Авторизация;
				ПодключитьОбработчикОжидания("АвторизоватьсяНаПочтовомСервере", 0.1, Истина);
			КонецЕсли;
		КонецЕсли;
	ИначеЕсли ТекущаяСтраница = Элементы.Авторизация Тогда
		Если ЭтоВебКлиент() И Не ЗначениеЗаполнено(НастройкиАвторизации.АдресРегистрацииУстройства) Тогда
			Если Не ПолучитьКлючиДоступаКПочтовомуСерверу(КодПодтверждения, НастройкиАвторизации.АдресПолученияКлюча, КлиентскоеПриложение.ПолучитьКраткийЗаголовок()) Тогда
				ПроверкаЗавершиласьСОшибками = Истина;
			КонецЕсли;
		КонецЕсли;
		
		Если ТолькоАвторизация Тогда
			ТребуетсяПодтверждениеЗакрытияФормы = Ложь;
			Если ПроверкаЗавершиласьСОшибками Тогда
				Закрыть(Ложь);
			Иначе
				ЗаписатьНастройкиАвторизации();
				Закрыть(Истина);
			КонецЕсли;
			Возврат;
		КонецЕсли;
		
		Если ПроверкаЗавершиласьСОшибками Тогда
			СледующаяСтраница = Элементы.ПриПроверкеОбнаруженыОшибки;
		Иначе
			Если СпособНастройки = "Автоматически" Тогда
				СледующаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи;
			Иначе
				Если ИспользоватьДляОтправки Или ИспользоватьДляПолучения Тогда
					СледующаяСтраница = Элементы.НастройкаСервераИсходящейПочты;
				Иначе
					СледующаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	ИначеЕсли ТекущаяСтраница = Элементы.НастройкаСервераИсходящейПочты Тогда
		СледующаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи;
	ИначеЕсли ТекущаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи Тогда
		Если Команда = Неопределено Тогда
			Если ПроверкаЗавершиласьСОшибками Тогда
				СледующаяСтраница = Элементы.НастройкаУчетнойЗаписи;
			ИначеЕсли ПроверкаПропущена И СпособНастройки = "Автоматически" Тогда
				СпособНастройки = "Вручную";
				СледующаяСтраница = Элементы.НастройкаСервераИсходящейПочты;
			Иначе
				СледующаяСтраница = Элементы.УчетнаяЗаписьУспешноНастроена;
			КонецЕсли;
			ПроверкаПропущена = Ложь;
		Иначе
			ОтменитьВыполнениеЗадания(ИдентификаторЗадания);
			ИдентификаторЗадания = "";
			ПроверкаПропущена = Истина;
			НастроитьЭлементыТекущейСтраницы();
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	Если Отказ Тогда
		Возврат;
	КонецЕсли;
	
	Если СледующаяСтраница = Неопределено Тогда
		Закрыть(Истина);
	Иначе
		Элементы.Страницы.ТекущаяСтраница = СледующаяСтраница;
		НастроитьЭлементыТекущейСтраницы();
	КонецЕсли;
	
	Если Элементы.Страницы.ТекущаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи Тогда
		Если СпособНастройки = "Автоматически" Тогда
			ПодключитьОбработчикОжидания("НастроитьПараметрыПодключенияАвтоматически", 0.1, Истина);
		Иначе
			ПодключитьОбработчикОжидания("ВыполнитьПроверкуНастроек", 0.1, Истина);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьТекстыПоясненийПоРегистрацииПриложения()
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	Если Не ЗначениеЗаполнено(НастройкиАвторизации) Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭтоВебКлиент() Тогда
		АдресПеренаправления = НастройкиАвторизации.АдресПеренаправленияВебКлиент;
	Иначе
		АдресПеренаправления = НастройкиАвторизации.АдресПеренаправления;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(АдресПеренаправления) Тогда
		АдресПеренаправления = НастройкиАвторизации.АдресПеренаправленияПоУмолчанию;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(НастройкиАвторизации.ПояснениеПоАдресуПеренаправления)
		И Не ЗначениеЗаполнено(НастройкиАвторизации.ПояснениеПоИдентификаторуПриложения)
		И Не ЗначениеЗаполнено(НастройкиАвторизации.ПояснениеПоПаролюПриложения) Тогда
		Возврат;
	КонецЕсли;
	
	ПояснениеПоАдресуПеренаправления = НастройкиАвторизации.ПояснениеПоАдресуПеренаправления;
	ПояснениеПоИдентификаторуПриложения = НастройкиАвторизации.ПояснениеПоИдентификаторуПриложения;
	ПояснениеПоПаролюПриложения = НастройкиАвторизации.ПояснениеПоПаролюПриложения;
	ДополнительноеПояснение = НастройкиАвторизации.ДополнительноеПояснение;
	
	ПсевдонимАдресаПеренаправления = НастройкиАвторизации.ПсевдонимАдресаПеренаправления;
	ПсевдонимИдентификатораПриложения = НастройкиАвторизации.ПсевдонимИдентификатораПриложения;
	ПсевдонимПароляПриложения = НастройкиАвторизации.ПсевдонимПароляПриложения;
	
	Элементы.ПояснениеПоАдресуПеренаправления.Заголовок = ПояснениеПоАдресуПеренаправления;
	Элементы.ПояснениеПоИдентификаторуПриложения.Заголовок = ПояснениеПоИдентификаторуПриложения;
	Элементы.ПояснениеПоПаролюПриложения.Заголовок = ПояснениеПоПаролюПриложения;
	Элементы.ДополнительноеПояснение.Заголовок = ДополнительноеПояснение;
	
	Элементы.АдресПеренаправления.Заголовок = ПсевдонимАдресаПеренаправления;
	Элементы.ИдентификаторПриложения.Заголовок = ПсевдонимИдентификатораПриложения;
	Элементы.ПарольПриложения.Заголовок = ПсевдонимПароляПриложения;
	
	Элементы.ПояснениеПоПаролюПриложения.Видимость = НастройкиАвторизации.ИспользоватьПарольПриложения;
	Элементы.ПарольПриложения.Видимость = НастройкиАвторизации.ИспользоватьПарольПриложения;
	
	Элементы.ПояснениеПоАдресуПеренаправления.Видимость = ЗначениеЗаполнено(ПояснениеПоАдресуПеренаправления);
	Элементы.ПояснениеПоИдентификаторуПриложения.Видимость = ЗначениеЗаполнено(ПояснениеПоИдентификаторуПриложения);
	Элементы.ПояснениеПоПаролюПриложения.Видимость = ЗначениеЗаполнено(ПояснениеПоПаролюПриложения);
	
	Элементы.АдресПеренаправления.Видимость = ЗначениеЗаполнено(ПсевдонимАдресаПеренаправления);
	
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьПроверкуНастроек()
	
	ОповещениеОЗакрытии = Новый ОписаниеОповещения("ВыполнитьПроверкуНастроекЗапросНаРазрешенияВыполнен", ЭтотОбъект);
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.ПрофилиБезопасности") Тогда
		Запрос = СоздатьЗапросНаИспользованиеВнешнихРесурсов();
		
		МодульРаботаВБезопасномРежимеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("РаботаВБезопасномРежимеКлиент");
		МодульРаботаВБезопасномРежимеКлиент.ПрименитьЗапросыНаИспользованиеВнешнихРесурсов(
			ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Запрос), ЭтотОбъект, ОповещениеОЗакрытии);
	Иначе
		ВыполнитьОбработкуОповещения(ОповещениеОЗакрытии, КодВозвратаДиалога.ОК);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьПроверкуНастроекЗапросНаРазрешенияВыполнен(РезультатЗапроса, ДополнительныеПараметры) Экспорт
	Если Не РезультатЗапроса = КодВозвратаДиалога.ОК Тогда
		Возврат;
	КонецЕсли;
	
	ПроверитьНастройкиУчетнойЗаписи();
	Если ЗначениеЗаполнено(УчетнаяЗаписьСсылка) Тогда 
		ОбщегоНазначенияКлиент.ОповеститьОбИзмененииОбъекта(УчетнаяЗаписьСсылка);
	КонецЕсли;
	ПерейтиНаСледующуюСтраницу();
КонецПроцедуры

&НаСервере
Функция СоздатьЗапросНаИспользованиеВнешнихРесурсов()
	
	МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме");
	
	Возврат МодульРаботаВБезопасномРежиме.ЗапросНаИспользованиеВнешнихРесурсов(
		Разрешения(), СсылкаНовойУчетнойЗаписи);
	
КонецФункции

&НаСервере
Функция Разрешения()
	
	Результат = Новый Массив;
	
	МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме");
	
	Если ИспользоватьДляОтправки Тогда
		Результат.Добавить(
			МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеИнтернетРесурса(
				"SMTP",
				СерверИсходящейПочты,
				ПортСервераИсходящейПочты,
				НСтр("ru = 'Электронная почта.'")));
	КонецЕсли;
	
	Если ИспользоватьДляПолучения Тогда
		Результат.Добавить(
			МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеИнтернетРесурса(
				Протокол,
				СерверВходящейПочты,
				ПортСервераВходящейПочты,
				НСтр("ru = 'Электронная почта.'")));
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

&НаКлиенте
Процедура ПроверитьЗаполнениеНаСтраницеНастройкаУчетнойЗаписи(Отказ)
	
	ОчиститьСообщения();
	
	Если ПустаяСтрока(АдресЭлектроннойПочты) Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр("ru = 'Введите адрес электронной почты'"), , "АдресЭлектроннойПочты", , Отказ);
	ИначеЕсли Не ОбщегоНазначенияКлиентСервер.АдресЭлектроннойПочтыСоответствуетТребованиям(АдресЭлектроннойПочты, Истина) Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр("ru = 'Адрес электронной почты введен неверно'"), , "АдресЭлектроннойПочты", , Отказ);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура НастроитьЭлементыТекущейСтраницы()
	
	ТекущаяСтраница = Элементы.Страницы.ТекущаяСтраница;
	
	// КнопкаДалее
	Если ТекущаяСтраница = Элементы.УчетнаяЗаписьУспешноНастроена Тогда
		Если КонтекстныйРежим Тогда
			ЗаголовокКнопкиДалее = НСтр("ru = 'Продолжить'");
		Иначе
			ЗаголовокКнопкиДалее = НСтр("ru = 'Закрыть'");
		КонецЕсли;
	Иначе
		Если ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи
			И ПроверкаЗавершиласьСОшибками Или ТекущаяСтраница = Элементы.ТехническиеПодробностиОшибки Тогда
				ЗаголовокКнопкиДалее = НСтр("ru = 'Повторить'");
		ИначеЕсли ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи
			И СпособНастройки = "Автоматически" Тогда
			Если КонтекстныйРежим Или Перенастройка Тогда
				ЗаголовокКнопкиДалее = НСтр("ru = 'Настроить'");
			Иначе
				ЗаголовокКнопкиДалее = НСтр("ru = 'Создать'");
			КонецЕсли;
		ИначеЕсли ТекущаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи Тогда
			ЗаголовокКнопкиДалее = НСтр("ru = 'Пропустить проверку'");
		Иначе
			ЗаголовокКнопкиДалее = НСтр("ru = 'Далее >'");
		КонецЕсли;
	КонецЕсли;
	
	Элементы.КнопкаДалее.Заголовок = ЗаголовокКнопкиДалее;
	Элементы.КнопкаДалее.КнопкаПоУмолчанию = ТекущаяСтраница <> Элементы.ПроверкаНастроекУчетнойЗаписи; 
	Элементы.КнопкаДалее.Доступность = Не (ТекущаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи И ПроверкаПропущена);
	Элементы.КнопкаДалее.Видимость = Не (ТекущаяСтраница = Элементы.ПроверкаНастроекУчетнойЗаписи И СпособНастройки = "Вручную")
		И Не (ТекущаяСтраница = Элементы.Авторизация И Не ЭтоВебКлиент())
		И Не ТекущаяСтраница = Элементы.ПриПроверкеОбнаруженыОшибки;
	
	Элементы.КнопкаНазад.Видимость = ТекущаяСтраница <> Элементы.НастройкаУчетнойЗаписи
		И ТекущаяСтраница <> Элементы.УчетнаяЗаписьУспешноНастроена
		И ТекущаяСтраница <> Элементы.ПроверкаНастроекУчетнойЗаписи
		И Не ТолькоАвторизация;
	
	Элементы.КнопкаОтмена.Видимость = ТекущаяСтраница <> Элементы.УчетнаяЗаписьУспешноНастроена;
	
	Элементы.КнопкаПерейтиКНастройкам.Видимость = Не ИспользуютсяПрофилиБезопасности И (ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи
		И ПроверкаЗавершиласьСОшибками Или Не КонтекстныйРежим И Не Перенастройка И ТекущаяСтраница = Элементы.УчетнаяЗаписьУспешноНастроена);
		
	Если Не КонтекстныйРежим И ТекущаяСтраница = Элементы.УчетнаяЗаписьУспешноНастроена Тогда
		Элементы.КнопкаПерейтиКНастройкам.Заголовок = НСтр("ru = 'Перейти к настройкам'");
	Иначе
		Элементы.КнопкаПерейтиКНастройкам.Заголовок = НСтр("ru = 'Настроить вручную'");
	КонецЕсли;

	
	Если ТекущаяСтраница = Элементы.НастройкаУчетнойЗаписи Тогда
		Элементы.НеУдалосьПодключитьсяКартинкаИНадпись.Видимость = ПроверкаЗавершиласьСОшибками;
		Элементы.Пароль.Доступность = СпособАутентификации = "Пароль";
	КонецЕсли;
	
	Если ТекущаяСтраница = Элементы.НастройкаСервераИсходящейПочты Тогда
		ОбновитьДоступностьНастройкиДнейДоУдаления();
		УстановитьВидимостьЭлементов();
	КонецЕсли;
	
	Если ТекущаяСтраница = Элементы.УчетнаяЗаписьУспешноНастроена Тогда
		Элементы.НадписьУчетнаяЗаписьУспешноНастроена.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Настройка почты
				|%1 успешно завершена.'"), АдресЭлектроннойПочты);
	КонецЕсли;
	
	Если ТекущаяСтраница = Элементы.Авторизация 
		И Элементы.ВариантыАвторизации.ТекущаяСтраница = Элементы.ВстроенныйБраузер Тогда
		Активизировать();
		ПодключитьОбработчикОжидания("ПроверитьРезультатАвторизации", 5, Истина );
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьДоступностьНастройкиДнейДоУдаления()
	Элементы.УдалятьПисьмаССервера.Доступность = ОставлятьКопииПисемНаСервере;
	Элементы.ПериодХраненияСообщенийНаСервере.Доступность = УдалятьПисьмаССервера;
КонецПроцедуры

&НаКлиенте
Процедура УстановитьВидимостьЭлементов()
	Элементы.ОставлятьПисьмаНаСервере.Видимость = Протокол = "POP";
КонецПроцедуры

&НаКлиенте
Процедура ПерейтиКНастройкам(Команда)
	ТекущаяСтраница = Элементы.Страницы.ТекущаяСтраница;
	Если Не КонтекстныйРежим И ТекущаяСтраница = Элементы.УчетнаяЗаписьУспешноНастроена Тогда
		ПоказатьЗначение(,УчетнаяЗаписьСсылка);
		Закрыть(Истина);
	Иначе
		Если СпособНастройки = "Автоматически" Тогда
			СпособНастройки = "Вручную";
		КонецЕсли;
		Элементы.Страницы.ТекущаяСтраница = Элементы.НастройкаСервераИсходящейПочты;
		НастроитьЭлементыТекущейСтраницы();
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьНастройкиУчетнойЗаписи()
	ЗаполнитьЗначенияСвойств(ЭтотОбъект, НастройкиПоУмолчанию(АдресЭлектроннойПочты, ПарольДляПолученияПисем));
	Если ПустаяСтрока(НазваниеУчетнойЗаписи) Тогда
		НазваниеУчетнойЗаписи = АдресЭлектроннойПочты;
	КонецЕсли;

	НастройкиЗаполнены = Истина;
	
	ШифрованиеПриОтправкеПочты = ?(ИспользоватьЗащищенноеСоединениеДляИсходящейПочты, "SSL", "Авто");
	ШифрованиеПриПолученииПочты = ?(ИспользоватьЗащищенноеСоединениеДляВходящейПочты, "SSL", "Авто");
КонецПроцедуры

&НаСервереБезКонтекста
Функция НастройкиПоУмолчанию(АдресЭлектроннойПочты, Пароль)
	
	Позиция = СтрНайти(АдресЭлектроннойПочты, "@");
	ИмяСервераВУчетнойЗаписи = Сред(АдресЭлектроннойПочты, Позиция + 1);
	
	Настройки = Новый Структура;
	
	Настройки.Вставить("ИмяПользователяДляПолученияПисем", АдресЭлектроннойПочты);
	Настройки.Вставить("ИмяПользователяДляОтправкиПисем", АдресЭлектроннойПочты);
	
	Настройки.Вставить("ПарольДляОтправкиПисем", Пароль);
	Настройки.Вставить("ПарольДляПолученияПисем", Пароль);
	
	Настройки.Вставить("Протокол", "IMAP");
	Настройки.Вставить("СерверВходящейПочты", "imap." + ИмяСервераВУчетнойЗаписи);
	Настройки.Вставить("ПортСервераВходящейПочты", 993);
	Настройки.Вставить("ИспользоватьЗащищенноеСоединениеДляВходящейПочты", Истина);
	
	Настройки.Вставить("СерверИсходящейПочты", "smtp." + ИмяСервераВУчетнойЗаписи);
	Настройки.Вставить("ПортСервераИсходящейПочты", 587);
	Настройки.Вставить("ИспользоватьЗащищенноеСоединениеДляИсходящейПочты", Ложь);
	
	Настройки.Вставить("ДлительностьОжиданияСервера", 30);
	Настройки.Вставить("ОставлятьКопииПисемНаСервере", Истина);
	Настройки.Вставить("ПериодХраненияСообщенийНаСервере", 10);
	
	НастройкиIMAPПоУмолчанию = Справочники.УчетныеЗаписиЭлектроннойПочты.ВариантыНастройкиПодключенияКСерверуIMAP(АдресЭлектроннойПочты)[0];
	НастройкиSMTPПоУмолчанию = Справочники.УчетныеЗаписиЭлектроннойПочты.ВариантыНастройкиПодключенияКСерверуSMTP(АдресЭлектроннойПочты)[0];
	
	ЗаполнитьЗначенияСвойств(Настройки, НастройкиIMAPПоУмолчанию);
	ЗаполнитьЗначенияСвойств(Настройки, НастройкиSMTPПоУмолчанию);
	
	Возврат Настройки;
КонецФункции

&НаСервере
Процедура ПроверитьНастройкиУчетнойЗаписи()
	
	ПрофильИсходящейПочты = Неопределено;
	Если ИспользоватьДляОтправки Тогда
		ПрофильИсходящейПочты = ИнтернетПочтовыйПрофиль(Ложь);
	КонецЕсли;

	ПрофильВходящейПочты = Неопределено;
	Если ИспользоватьДляПолучения Тогда
		ПрофильВходящейПочты = ИнтернетПочтовыйПрофиль(Истина);
	КонецЕсли;

	РезультатПроверки = Справочники.УчетныеЗаписиЭлектроннойПочты.ПроверитьНастройкиПрофилей(
		ПрофильИсходящейПочты, ПрофильВходящейПочты, АдресЭлектроннойПочты);
	
	СообщенияОбОшибках = РезультатПроверки.ОшибкиПодключения;
	ПроверкаЗавершиласьСОшибками = ЗначениеЗаполнено(СообщенияОбОшибках);
	
	Если Не ПроверкаЗавершиласьСОшибками Тогда
		Попытка
			СоздатьУчетнуюЗапись();
		Исключение
			ПроверкаЗавершиласьСОшибками = Истина;
			СообщенияОбОшибках = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		КонецПопытки;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура СоздатьУчетнуюЗапись()
	
	ПреобразоватьНастройкиИзPunycode();
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	СистемнаяУчетнаяЗапись = Справочники.УчетныеЗаписиЭлектроннойПочты.СистемнаяУчетнаяЗаписьЭлектроннойПочты;
	НастроитьСистемнуюУчетнуюЗапись = КонтекстныйРежим И ВидУчетнойЗаписи = "Общая"
		И Не РаботаСПочтовымиСообщениями.УчетнаяЗаписьНастроена(СистемнаяУчетнаяЗапись)
		И Справочники.УчетныеЗаписиЭлектроннойПочты.ИзменениеРазрешено(СистемнаяУчетнаяЗапись);
	
	Если НастроитьСистемнуюУчетнуюЗапись Тогда
		УчетнаяЗаписьСсылка = СистемнаяУчетнаяЗапись;
	КонецЕсли;
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("Справочник.УчетныеЗаписиЭлектроннойПочты");
	Если Не УчетнаяЗаписьСсылка.Пустая() Тогда
		ЭлементБлокировки.УстановитьЗначение("Ссылка", УчетнаяЗаписьСсылка);
	КонецЕсли;
	
	НачатьТранзакцию();
	Попытка
		Блокировка.Заблокировать();
		
		Если УчетнаяЗаписьСсылка.Пустая() Тогда
			УчетнаяЗапись = Справочники.УчетныеЗаписиЭлектроннойПочты.СоздатьЭлемент();
			УчетнаяЗапись.УстановитьСсылкуНового(СсылкаНовойУчетнойЗаписи);
		Иначе
			УчетнаяЗапись = УчетнаяЗаписьСсылка.ПолучитьОбъект();
		КонецЕсли;
		
		ЗаполнитьЗначенияСвойств(УчетнаяЗапись, ЭтотОбъект);
		УчетнаяЗапись.ИмяПользователя = ИмяОтправителяПисем;
		УчетнаяЗапись.Пользователь = ИмяПользователяДляПолученияПисем;
		УчетнаяЗапись.ПользовательSMTP = ИмяПользователяДляОтправкиПисем;
		УчетнаяЗапись.ВремяОжидания = ДлительностьОжиданияСервера;
		УчетнаяЗапись.ОставлятьКопииСообщенийНаСервере = ОставлятьКопииПисемНаСервере;
		УчетнаяЗапись.ПериодХраненияСообщенийНаСервере = ?(ОставлятьКопииПисемНаСервере И УдалятьПисьмаССервера И Протокол = "POP", ПериодХраненияСообщенийНаСервере, 0);
		УчетнаяЗапись.ПротоколВходящейПочты = Протокол;
		УчетнаяЗапись.Наименование = НазваниеУчетнойЗаписи;
		УчетнаяЗапись.ПриОтправкеПисемТребуетсяАвторизация = ЗначениеЗаполнено(УчетнаяЗапись.ПользовательSMTP);
		Если ВидУчетнойЗаписи = "Персональная" Тогда
			УчетнаяЗапись.ВладелецУчетнойЗаписи = Пользователи.ТекущийПользователь();
		Иначе
			УчетнаяЗапись.ВладелецУчетнойЗаписи = Справочники.Пользователи.ПустаяСсылка();
		КонецЕсли;
		УчетнаяЗапись.ДополнительныеСвойства.Вставить("НеПроверятьИзменениеНастроек");
		Если СпособАутентификации = "OAuth" Тогда
			УчетнаяЗапись.АвторизацияСПомощьюПочтовогоСервиса = Истина;
			УчетнаяЗапись.ИмяПочтовогоСервиса = НастройкиАвторизации.ИмяИнтернетСервиса;
		КонецЕсли;
		
		УчетнаяЗапись.Записать();
		УчетнаяЗаписьСсылка = УчетнаяЗапись.Ссылка;
		ТребуетсяПодтверждениеЗакрытияФормы = Ложь;
		
		УстановитьПривилегированныйРежим(Истина);
		
		ОбщегоНазначения.УдалитьДанныеИзБезопасногоХранилища(УчетнаяЗаписьСсылка);
		Если СпособАутентификации = "OAuth" Тогда
			ЗаписатьНастройкиАвторизации();
		Иначе
			ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(УчетнаяЗаписьСсылка, ПарольДляПолученияПисем);
			ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(УчетнаяЗаписьСсылка, ПарольДляОтправкиПисем, "ПарольSMTP");
		КонецЕсли;
		
		УстановитьПривилегированныйРежим(Ложь);
			
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации(НСтр("ru = 'Работа с почтовыми сообщениями'", ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка, , УчетнаяЗаписьСсылка, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

&НаСервере
Процедура ЗаписатьНастройкиАвторизации()

	УстановитьПривилегированныйРежим(Истина);

	ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(УчетнаяЗаписьСсылка, ТокенДоступа, "ТокенДоступа");
	ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(УчетнаяЗаписьСсылка, СрокДействияТокенаДоступа, "СрокДействияТокенаДоступа");
	ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище(УчетнаяЗаписьСсылка, ТокенОбновления, "ТокенОбновления");
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	НастройкиАвторизации.ПарольПриложения = ПарольПриложения;
	НастройкиАвторизации.ИдентификаторПриложения = ИдентификаторПриложения;
	НастройкиАвторизации.АдресПеренаправления = АдресПеренаправления;
	Справочники.НастройкиАвторизацииИнтернетСервисов.ЗаписатьНастройкиАвторизации(НастройкиАвторизации);
	
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры

&НаСервере
Функция ИнтернетПочтовыйПрофиль(ДляПолучения = Ложь)
	
	Профиль = Новый ИнтернетПочтовыйПрофиль;
	Если ДляПолучения Или ТребуетсяВходНаСерверПередОтправкой Тогда
		Если Протокол = "IMAP" Тогда
			Профиль.АдресСервераIMAP = СерверВходящейПочты;
			Профиль.ИспользоватьSSLIMAP = ИспользоватьЗащищенноеСоединениеДляВходящейПочты;
			Профиль.ПарольIMAP = ПарольДляПолученияПисем;
			Профиль.ПользовательIMAP = ИмяПользователяДляПолученияПисем;
			Профиль.ПортIMAP = ПортСервераВходящейПочты;
		Иначе
			Профиль.АдресСервераPOP3 = СерверВходящейПочты;
			Профиль.ИспользоватьSSLPOP3 = ИспользоватьЗащищенноеСоединениеДляВходящейПочты;
			Профиль.Пароль = ПарольДляПолученияПисем;
			Профиль.Пользователь = ИмяПользователяДляПолученияПисем;
			Профиль.ПортPOP3 = ПортСервераВходящейПочты;
		КонецЕсли;
	КонецЕсли;
	
	Если Не ДляПолучения Тогда
		Профиль.POP3ПередSMTP = ТребуетсяВходНаСерверПередОтправкой;
		Профиль.АдресСервераSMTP = СерверИсходящейПочты;
		Профиль.ИспользоватьSSLSMTP = ИспользоватьЗащищенноеСоединениеДляИсходящейПочты;
		Профиль.ПарольSMTP = ПарольДляОтправкиПисем;
		Профиль.ПользовательSMTP = ИмяПользователяДляОтправкиПисем;
		Профиль.ПортSMTP = ПортСервераИсходящейПочты;
	КонецЕсли;
	
	Профиль.Таймаут = ДлительностьОжиданияСервера;
	
	Если СпособАутентификации = "OAuth" Тогда
		Профиль.АутентификацияПоТокену = ИспользованиеАутентификацииИнтернетПочтыПоТокену.Использовать;
		Профиль.ТокенДоступа = ТокенДоступа;
	КонецЕсли;
	
	Возврат Профиль;
	
КонецФункции

&НаКлиенте
Процедура НастроитьПараметрыПодключенияАвтоматически()
	
	СообщенияОбОшибках = НСтр("ru = 'Не удалось определить настройки подключения. 
	|Настройте параметры подключения вручную.'");
	
	ПроверкаЗавершиласьСОшибками = Ложь;
	
	ДлительнаяОперация = НачатьПоискНастроекУчетнойЗаписи();
	ИдентификаторЗадания = ДлительнаяОперация.ИдентификаторЗадания;
	
	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;
	
	ОписаниеОповещения = Новый ОписаниеОповещения("ПриЗавершенииПоискаНастроек", ЭтотОбъект);
	ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОписаниеОповещения, ПараметрыОжидания);
	
КонецПроцедуры

&НаСервере
Функция НачатьПоискНастроекУчетнойЗаписи()
	
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Поиск настроек почтового сервера'");
	
	Возврат ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения, "Справочники.УчетныеЗаписиЭлектроннойПочты.ОпределитьНастройкиУчетнойЗаписи",
		АдресЭлектроннойПочты, ПарольДляПолученияПисем, ИспользоватьДляОтправки, ИспользоватьДляПолучения);
	
КонецФункции

&НаКлиенте
Процедура ПриЗавершенииПоискаНастроек(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		Если ПроверкаПропущена И Открыта() Тогда
			ПерейтиНаСледующуюСтраницу();
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	Если Результат.Статус = "Ошибка" Тогда
		ПроверкаЗавершиласьСОшибками = Истина;
		ПерейтиНаСледующуюСтраницу();
		Возврат;
	КонецЕсли;
	
	НайденныеНастройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
	
	ПроверкаЗавершиласьСОшибками = ИспользоватьДляОтправки И Не НайденныеНастройки.ДляОтправки 
		Или ИспользоватьДляПолучения И Не НайденныеНастройки.ДляПолучения;
		
	ЗаполнитьЗначенияСвойств(ЭтотОбъект, НайденныеНастройки);
	ШифрованиеПриОтправкеПочты = ?(ИспользоватьЗащищенноеСоединениеДляИсходящейПочты, "SSL", "Авто");
	ШифрованиеПриПолученииПочты = ?(ИспользоватьЗащищенноеСоединениеДляВходящейПочты, "SSL", "Авто");
	
	Если Не НайденныеНастройки.ПроверкаНастроекВыполнена Тогда
		ПодключитьОбработчикОжидания("ВыполнитьПроверкуНастроек", 0.1, Истина);
		Возврат;
	КонецЕсли;

	Если Не ПроверкаЗавершиласьСОшибками Тогда
		Попытка
			СоздатьУчетнуюЗапись();
		Исключение
			ПроверкаЗавершиласьСОшибками = Истина;
			СообщенияОбОшибках = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		КонецПопытки;
		Если Не ПроверкаЗавершиласьСОшибками Тогда
			ОбщегоНазначенияКлиент.ОповеститьОбИзмененииОбъекта(СсылкаНовойУчетнойЗаписи);	
		КонецЕсли;
	КонецЕсли;
	ПерейтиНаСледующуюСтраницу();
	
КонецПроцедуры

&НаКлиенте
Процедура ПарольНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	РаботаСПочтовымиСообщениямиКлиент.ПолеПароляНачалоВыбора(Элемент, ПарольДляПолученияПисем, СтандартнаяОбработка);
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ОтменитьВыполнениеЗадания(ИдентификаторЗадания)
	Если ЗначениеЗаполнено(ИдентификаторЗадания) Тогда 
		ДлительныеОперации.ОтменитьВыполнениеЗадания(ИдентификаторЗадания);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьПереходПоАдресу(Знач АдресПерехода)
	
	СтруктураАдреса = ОбщегоНазначенияКлиентСервер.СтруктураURI(АдресПерехода);
	Если Не ЗначениеЗаполнено(СтруктураАдреса.Схема) Тогда
		АдресПерехода = "http://" + АдресПерехода;
	КонецЕсли;
	
	Если ЭтоВебКлиент() Тогда
		ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(АдресПерехода);
		Возврат;
	КонецЕсли;

	ВебСтраница = 
	"<!DOCTYPE html>
	|<html>
	|	<body>
	|		<script language = 'javascript'>
	|			document.location.href='" + АдресПерехода + "';
	|		</script>
	|		<p>Загрузка...</p>
	|	</body>
	|</html>";
	
КонецПроцедуры

&НаКлиенте
Процедура АвторизоватьсяНаПочтовомСервере()
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	СтрокаЗапросаАвторизации = СтрокаЗапросаАвторизации();
	
	Если ЭтоВебКлиент() Тогда
		Если ЗначениеЗаполнено(НастройкиАвторизации.АдресРегистрацииУстройства) Тогда
			Если ПолучитьПараметрыАвторизацииВВебКлиенте(НастройкиАвторизации.АдресРегистрацииУстройства) Тогда
				СтрокаЗапросаАвторизации = АдресАвторизацииПользователя;
				Если Не ЗначениеЗаполнено(ИнтервалВыполненияЗапросов) Тогда
					ИнтервалВыполненияЗапросов = 5;
				КонецЕсли;
				ПодключитьОбработчикОжидания("ПолучитьКлючиДоступаВебКлиент", ИнтервалВыполненияЗапросов, Истина);
			Иначе
				ЗаполнитьПояснения();
				ПерейтиНаСледующуюСтраницу();
				Возврат;
			КонецЕсли;
		КонецЕсли;
		
		Элементы.ПояснениеПоКодуПодтверждения.Заголовок = СтроковыеФункцииКлиент.ФорматированнаяСтрока(НСтр(
			"ru = 'Авторизуйтесь на <a href=""%1"">странице почтового сервиса</a> и введите полученный код в поле ниже:'"),
			СтрокаЗапросаАвторизации);
		Элементы.ВариантыАвторизации.ТекущаяСтраница = Элементы.БраузерОперационнойСистемы;

	Иначе
		Элементы.ВариантыАвторизации.ТекущаяСтраница = Элементы.ВстроенныйБраузер;
		ВыполнитьПереходПоАдресу(СтрокаЗапросаАвторизации);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция СтрокаЗапросаАвторизации()

	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(НастройкиАвторизации.АдресАвторизации);
	АдресСервера = СтруктураURI.Хост;
	АдресРесурса = "/" + СтруктураURI.ПутьНаСервере;
	
	ИдентификаторЗапроса = Строка(Новый УникальныйИдентификатор());
	ПроверочныйКод = РаботаСПочтовымиСообщениямиСлужебный.СгенерироватьПроверочныйКод();

	Если ЭтоВебКлиент() Тогда
		Если Не ЗначениеЗаполнено(НастройкиАвторизации.АдресРегистрацииУстройства) Тогда
			ИдентификаторУстройства = Строка(Новый УникальныйИдентификатор());
		КонецЕсли;
	КонецЕсли;	
	
	ПараметрыЗапроса = ПараметрыЗапросаАвторизации();
	HTTPЗапрос = РаботаСПочтовымиСообщениямиСлужебный.ПодготовитьHTTPЗапрос(АдресРесурса, ПараметрыЗапроса, Ложь);
	
	СтрокаЗапроса = "https://" + АдресСервера + HTTPЗапрос.АдресРесурса;
	Возврат СтрокаЗапроса; 
	
КонецФункции

&НаСервере
Функция ПараметрыЗапросаАвторизации()
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("client_id", ИдентификаторПриложения);
	ПараметрыЗапроса.Вставить("response_type", "code");
	ПараметрыЗапроса.Вставить("redirect_uri", АдресПеренаправления);
	
	Если ЗначениеЗаполнено(НастройкиАвторизации["ЗапрашиваемыеРазрешения"]) Тогда
		ПараметрыЗапроса.Вставить("scope", НастройкиАвторизации["ЗапрашиваемыеРазрешения"]);
	КонецЕсли;
	
	ПараметрыЗапроса.Вставить("state", ИдентификаторЗапроса);
	ПараметрыЗапроса.Вставить("login_hint", АдресЭлектроннойПочты);
	
	Если НастройкиАвторизации.ИспользоватьКлючПроверкиПодлинностиPKCE Тогда
		ПараметрыЗапроса.Вставить("code_challenge", РаботаСПочтовымиСообщениямиСлужебный.КодироватьСтрокуМетодомS256(ПроверочныйКод));
		ПараметрыЗапроса.Вставить("code_challenge_method", "S256");
	КонецЕсли;
	
	Если ЗначениеЗаполнено(НастройкиАвторизации["ДополнительныеПараметрыАвторизации"]) Тогда
		Для Каждого Элемент Из СтрРазделить(НастройкиАвторизации["ДополнительныеПараметрыАвторизации"], " ", Ложь) Цикл
			ОписаниеПараметра = СтрРазделить(Элемент, "=", Истина);
			ИмяПараметра = ОписаниеПараметра[0];
			ЗначениеПараметра = "";
			Если ОписаниеПараметра.Количество() = 2 Тогда
				ЗначениеПараметра = ОписаниеПараметра[1];
			КонецЕсли;
			ПараметрыЗапроса.Вставить(ИмяПараметра, ЗначениеПараметра);
		КонецЦикла;
	КонецЕсли;

	Если ЭтоВебКлиент() Тогда
		Если Не ЗначениеЗаполнено(НастройкиАвторизации.АдресРегистрацииУстройства) Тогда
			ПараметрыЗапроса.Вставить("device_name", НСтр("ru = '1С:Предприятие'"));
		КонецЕсли;
		ПараметрыЗапроса.Вставить("device_id", ИдентификаторУстройства);
	КонецЕсли;
	
	Возврат ПараметрыЗапроса;
	
КонецФункции

&НаКлиенте
Процедура ВебСтраницаДокументСформирован(Элемент)

	ПроверитьРезультатАвторизации();

КонецПроцедуры

&НаКлиенте
Процедура ПроверитьРезультатАвторизации()
	
#Если Не ВебКлиент Тогда
	
	ОтключитьОбработчикОжидания("ПроверитьРезультатАвторизации");
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	АдресПолученияКлюча = НастройкиАвторизации.АдресПолученияКлюча;
	
	ОтветСервера = "";
	Если СтрНачинаетсяС(НРег(Элементы.ВебСтраница.Документ.URL), НРег(АдресПеренаправления)) Тогда
		ОтветСервера = Элементы.ВебСтраница.Документ.URL;
	ИначеЕсли СтрНачинаетсяС(ВебСтраница, "{") И СтрЗаканчиваетсяНа(ВебСтраница, "}") Тогда
		ОтветСервера = ВебСтраница;
	ИначеЕсли Элементы.ВебСтраница.Документ.contentType = "application/json"
		И Элементы.ВебСтраница.Документ.body <> Неопределено Тогда
		ОтветСервера = Элементы.ВебСтраница.Документ.body.innerText;
	ИначеЕсли Элементы.ВебСтраница.Документ.body <> Неопределено 
		И СтрНайти(Элементы.ВебСтраница.Документ.body.innerText, АдресПеренаправления) Тогда
		ЧастиСтроки = СтрРазделить(Элементы.ВебСтраница.Документ.body.innerText, " ", Ложь);
		Для Каждого ЧастьСтроки Из ЧастиСтроки Цикл
			Если СтрНачинаетсяС(ЧастьСтроки, АдресПеренаправления) Тогда
				ОтветСервера = ЧастьСтроки;
				Прервать;
			КонецЕсли;
		КонецЦикла;
	Иначе
		Если Элементы.Страницы.ТекущаяСтраница = Элементы.Авторизация Тогда
			ПодключитьОбработчикОжидания("ПроверитьРезультатАвторизации", 5, Истина);
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	ПриПолученииОтветаПочтовогоСервера(ОтветСервера, АдресПолученияКлюча);
	ПерейтиНаСледующуюСтраницу();
#КонецЕсли

КонецПроцедуры

&НаСервере
Процедура ПриПолученииОтветаПочтовогоСервера(СтрокаПараметров, АдресПолученияКлюча)
	
	Если СтрНачинаетсяС(СтрокаПараметров, "{") Тогда
		Ответ = ОбщегоНазначения.JSONВЗначение(СтрокаПараметров);
	Иначе
		Ответ = ПараметрыИзСтрокиURI(СтрокаПараметров);
	КонецЕсли;
	
	КодАвторизации = Ответ["code"];
	КодОшибки = Ответ["error"];
	ТекстОшибки = Ответ["error_description"];
	
	Если ЗначениеЗаполнено(ТекстОшибки) Тогда
		ТекстОшибки = РаскодироватьСтроку(ТекстОшибки, СпособКодированияСтроки.КодировкаURL);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(КодОшибки) Тогда
		СообщенияОбОшибках = ОписаниеОшибкиАвторизацииПочтовогоСервера(КодОшибки, ТекстОшибки);
		ПроверкаЗавершиласьСОшибками = Истина;
	ИначеЕсли ИдентификаторЗапроса <> Ответ["state"] Тогда
		СообщенияОбОшибках = НСтр("ru = 'Не удалось авторизоваться на почтовом сервере. Неверный идентификатор ответа.'");
		ПроверкаЗавершиласьСОшибками = Истина;
	ИначеЕсли Не ПолучитьКлючиДоступаКПочтовомуСерверу(КодАвторизации, АдресПолученияКлюча) Тогда
		ПроверкаЗавершиласьСОшибками = Истина;
	КонецЕсли;
	
	Если ПроверкаЗавершиласьСОшибками Тогда
		ЗаполнитьПояснения();
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция ПолучитьКлючиДоступаКПочтовомуСерверу(КодАвторизации, АдресПолученияКлюча, ЗаголовокПриложения = "")
	
	СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(АдресПолученияКлюча);
	АдресСервера = СтруктураURI.Хост;
	АдресРесурса = "/" + СтруктураURI.ПутьНаСервере;
	
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("client_id", ИдентификаторПриложения);
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	Если ЗначениеЗаполнено(НастройкиАвторизации["ЗапрашиваемыеРазрешения"]) Тогда
		ПараметрыЗапроса.Вставить("scope", НастройкиАвторизации["ЗапрашиваемыеРазрешения"]);
	КонецЕсли;

	ПараметрыЗапроса.Вставить("code", КодАвторизации);
	ПараметрыЗапроса.Вставить("redirect_uri", АдресПеренаправления);
	ПараметрыЗапроса.Вставить("grant_type", "authorization_code");
	
	Если НастройкиАвторизации.ИспользоватьКлючПроверкиПодлинностиPKCE Тогда
		ПараметрыЗапроса.Вставить("code_verifier", ПроверочныйКод);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ПарольПриложения) Тогда
		ПараметрыЗапроса.Вставить("client_secret", ПарольПриложения);
	КонецЕсли;

	Если ЭтоВебКлиент() Тогда
		ПараметрыЗапроса.Вставить("device_id", ИдентификаторУстройства);
		ПараметрыЗапроса.Вставить("device_name", ЗаголовокПриложения);
	КонецЕсли;
	
	ВремяЗапроса = ТекущаяДатаСеанса();
	
	РезультатЗапроса = РаботаСПочтовымиСообщениямиСлужебный.ВыполнитьЗапрос(АдресСервера, АдресРесурса, ПараметрыЗапроса);
	
	Попытка
		ПараметрыОтвета = ОбщегоНазначения.JSONВЗначение(РезультатЗапроса.ОтветСервера);
	Исключение
		ПараметрыОтвета = Новый Соответствие;
	КонецПопытки;
	
	ТокенДоступа = ПараметрыОтвета["access_token"];
	СрокДействияТокенаДоступа = ПараметрыОтвета["expires_in"];
	ТокенОбновления = ПараметрыОтвета["refresh_token"];
	КодОшибки = ПараметрыОтвета["error"];
	ТекстОшибки = ПараметрыОтвета["error_description"];
	
	Если ЗначениеЗаполнено(КодОшибки) Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось получить ключи доступа к учетной записи почты %1 по причине:
			|%2'"), АдресЭлектроннойПочты, ТекстОшибки);
			
		ТехническиеПодробности = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Ответ сервера:
			|%1'"), РезультатЗапроса.ОтветСервера);
			
		ЗаписьЖурналаРегистрации(РаботаСПочтовымиСообщениямиСлужебный.ИмяСобытияАвторизацияПоПротоколуOAuth(),
			УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки + Символы.ПС + ТехническиеПодробности);
		СообщенияОбОшибках = ТекстОшибки;
		Возврат Ложь;
	ИначеЕсли Не РезультатЗапроса.ЗапросВыполнен Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось получить ключи доступа к учетной записи почты %1 по причине:
			|Запрос не выполнен.'"), АдресЭлектроннойПочты);
			
		ТехническиеПодробности = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Ответ сервера:
			|%1'"), РезультатЗапроса.ОтветСервера);
			
		ЗаписьЖурналаРегистрации(РаботаСПочтовымиСообщениямиСлужебный.ИмяСобытияАвторизацияПоПротоколуOAuth(),
			УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки + Символы.ПС + ТехническиеПодробности);
		СообщенияОбОшибках = ТекстОшибки;
		Возврат Ложь;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СрокДействияТокенаДоступа) Тогда
		СрокДействияТокенаДоступа = ВремяЗапроса + СрокДействияТокенаДоступа;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

&НаСервере
Функция ПараметрыИзСтрокиURI(СтрокаURI)

	ЗначенияПараметров = Новый Соответствие;
	СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(СтрокаURI);
	Для Каждого ЧастьСтроки Из СтрРазделить(СтруктураURI.ПутьНаСервере, "?&") Цикл
		ПараметрИЗначение = СтрРазделить(ЧастьСтроки, "=", Истина);
		ИмяПараметра = ПараметрИЗначение[0];
		Если ПараметрИЗначение.Количество() > 1 Тогда
			ЗначениеПараметра = РаскодироватьСтроку(ПараметрИЗначение[1], СпособКодированияСтроки.КодировкаURL);
			ЗначенияПараметров.Вставить(ИмяПараметра, ЗначениеПараметра);
		КонецЕсли;
	КонецЦикла;
	
	Возврат ЗначенияПараметров;
	
КонецФункции

&НаСервереБезКонтекста
Функция ОписаниеОшибкиАвторизацииПочтовогоСервера(Знач КодОшибки, Знач ТекстОшибки)
	
	Результат = Строка(ТекстОшибки) + Символы.ПС + КодОшибки;
	Результат = СокрЛП(Результат);
	
	Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(
		"ru = 'Не удалось авторизоваться на почтовом сервере:
		|%1'"), Результат);
	
	Возврат Результат;
	
КонецФункции

// Возвращаемое значение:
//   см. Справочники.УчетныеЗаписиЭлектроннойПочты.НастройкиПодключенияПоАдресуЭлектроннойПочты
//
&НаСервере
Функция НастройкиПодключенияПоАдресуЭлектроннойПочты()
	
	УстановитьПривилегированныйРежим(Истина);
	Возврат Справочники.УчетныеЗаписиЭлектроннойПочты.НастройкиПодключенияПоАдресуЭлектроннойПочты(АдресЭлектроннойПочты, ПарольДляПолученияПисем);
	
КонецФункции	

// Возвращаемое значение:
//   см. Справочники.НастройкиАвторизацииИнтернетСервисов.НастройкиАвторизацииИнтернетСервиса
//
&НаСервере
Функция НастройкиАвторизацииНаПочтовомСервере()
	
	Возврат НастройкиПодключенияПоАдресуЭлектроннойПочты().НастройкиАвторизации;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ЭтоВебКлиент()
	
#Если ВебКлиент Тогда
	Возврат Истина;
#КонецЕсли
	
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
	Возврат ОбщегоНазначения.ЭтоВебКлиент();
#КонецЕсли
	
	Возврат Ложь;
	
КонецФункции

&НаСервере
Функция ПолучитьПараметрыАвторизацииВВебКлиенте(АдресПолученияКлюча)
	
	СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(АдресПолученияКлюча);
	АдресСервера = СтруктураURI.Хост;
	АдресРесурса = "/" + СтруктураURI.ПутьНаСервере;
	
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("client_id", ИдентификаторПриложения);
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	Если ЗначениеЗаполнено(НастройкиАвторизации["ЗапрашиваемыеРазрешения"]) Тогда
		ПараметрыЗапроса.Вставить("scope", НастройкиАвторизации["ЗапрашиваемыеРазрешения"]);
	КонецЕсли;

	ВремяЗапроса = ТекущаяДатаСеанса();
	РезультатЗапроса = РаботаСПочтовымиСообщениямиСлужебный.ВыполнитьЗапрос(АдресСервера, АдресРесурса, ПараметрыЗапроса);
	
	Попытка
		ПараметрыОтвета = ОбщегоНазначения.JSONВЗначение(РезультатЗапроса.ОтветСервера);
	Исключение
		ПараметрыОтвета = Новый Соответствие;
	КонецПопытки;
	
	ИдентификаторУстройства = ПараметрыОтвета["device_code"];
	СрокДействияИдентификатораУстройства = ПараметрыОтвета["expires_in"];
	ИнтервалВыполненияЗапросов = ПараметрыОтвета["interval"];
	КодПодтверждения = ПараметрыОтвета["user_code"];
	
	АдресАвторизацииПользователя = ПараметрыОтвета["verification_url"];
	Если Не ЗначениеЗаполнено(АдресАвторизацииПользователя) Тогда
		АдресАвторизацииПользователя = ПараметрыОтвета["verification_uri"];
	КонецЕсли;
	
	КодОшибки = ПараметрыОтвета["error"];
	ТекстОшибки = ПараметрыОтвета["error_description"];
	ТекстОшибки = ОписаниеОшибкиАвторизацииПочтовогоСервера(КодОшибки, ТекстОшибки);
	
	Если ЗначениеЗаполнено(КодОшибки) Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось получить ключи доступа к учетной записи почты %1 по причине:
			|%2'"), АдресЭлектроннойПочты, ТекстОшибки);
			
		ТехническиеПодробности = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Ответ сервера:
			|%1'"), РезультатЗапроса.ОтветСервера);
			
		ЗаписьЖурналаРегистрации(РаботаСПочтовымиСообщениямиСлужебный.ИмяСобытияАвторизацияПоПротоколуOAuth(),
			УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки + Символы.ПС + ТехническиеПодробности);
		СообщенияОбОшибках = ТекстОшибки;
		ПроверкаЗавершиласьСОшибками = Истина;
		Возврат Ложь;
	ИначеЕсли Не РезультатЗапроса.ЗапросВыполнен Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось получить ключи доступа к учетной записи почты %1 по причине:
			|Запрос не выполнен.'"), АдресЭлектроннойПочты);
			
		ТехническиеПодробности = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Ответ сервера:
			|%1'"), РезультатЗапроса.ОтветСервера);
			
		ЗаписьЖурналаРегистрации(РаботаСПочтовымиСообщениямиСлужебный.ИмяСобытияАвторизацияПоПротоколуOAuth(),
			УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки + Символы.ПС + ТехническиеПодробности);
		СообщенияОбОшибках = ТекстОшибки;
		ПроверкаЗавершиласьСОшибками = Истина;
		Возврат Ложь;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СрокДействияИдентификатораУстройства) Тогда
		СрокДействияИдентификатораУстройства = ВремяЗапроса + СрокДействияИдентификатораУстройства;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

&НаКлиенте
Процедура ПолучитьКлючиДоступаВебКлиент()
	
	Если ПолучитьКлючДоступаУстройства() = Неопределено Тогда
		ПодключитьОбработчикОжидания("ПолучитьКлючиДоступаВебКлиент", ИнтервалВыполненияЗапросов, Истина);
		Возврат;
	КонецЕсли;
	
	ПерейтиНаСледующуюСтраницу();
	
КонецПроцедуры

&НаСервере
Функция ПолучитьКлючДоступаУстройства()
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(НастройкиАвторизации.АдресПолученияКлюча);
	АдресСервера = СтруктураURI.Хост;
	АдресРесурса = "/" + СтруктураURI.ПутьНаСервере;
	
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("client_id", ИдентификаторПриложения);
	ПараметрыЗапроса.Вставить("client_secret", ПарольПриложения);
	ПараметрыЗапроса.Вставить("device_code", ИдентификаторУстройства);
	ПараметрыЗапроса.Вставить("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
	
	ВремяЗапроса = ТекущаяДатаСеанса();
	РезультатЗапроса = РаботаСПочтовымиСообщениямиСлужебный.ВыполнитьЗапрос(АдресСервера, АдресРесурса, ПараметрыЗапроса);
	
	Попытка
		ПараметрыОтвета = ОбщегоНазначения.JSONВЗначение(РезультатЗапроса.ОтветСервера);
	Исключение
		ПараметрыОтвета = Новый Соответствие;
	КонецПопытки;
	
	ТокенДоступа = ПараметрыОтвета["access_token"];
	СрокДействияТокенаДоступа = ПараметрыОтвета["expires_in"];
	ТокенОбновления = ПараметрыОтвета["refresh_token"];
	КодОшибки = ПараметрыОтвета["error"];
	ТекстОшибки = ПараметрыОтвета["error_description"];
	
	Если КодОшибки = "authorization_pending" Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(КодОшибки) Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось получить ключи доступа к учетной записи почты %1 по причине:
			|%2'"), АдресЭлектроннойПочты, ТекстОшибки);
			
		ТехническиеПодробности = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Ответ сервера:
			|%1'"), РезультатЗапроса.ОтветСервера);
			
		ЗаписьЖурналаРегистрации(РаботаСПочтовымиСообщениямиСлужебный.ИмяСобытияАвторизацияПоПротоколуOAuth(),
			УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки + Символы.ПС + ТехническиеПодробности);
		СообщенияОбОшибках = ТекстОшибки;
		Возврат Ложь;
	ИначеЕсли Не РезультатЗапроса.ЗапросВыполнен Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось получить ключи доступа к учетной записи почты %1 по причине:
			|Запрос не выполнен.'"), АдресЭлектроннойПочты);
			
		ТехническиеПодробности = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Ответ сервера:
			|%1'"), РезультатЗапроса.ОтветСервера);
			
		ЗаписьЖурналаРегистрации(РаботаСПочтовымиСообщениямиСлужебный.ИмяСобытияАвторизацияПоПротоколуOAuth(),
			УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки + Символы.ПС + ТехническиеПодробности);
		СообщенияОбОшибках = ТекстОшибки;
		Возврат Ложь;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СрокДействияТокенаДоступа) Тогда
		СрокДействияТокенаДоступа = ВремяЗапроса + СрокДействияТокенаДоступа;
	КонецЕсли;
	
	Возврат Истина;	
	
КонецФункции

&НаКлиенте
Процедура ПроверитьЗаполнениеНаСтраницеНастройкиАвторизацииПриложения(Отказ)
	
	ОчиститьСообщения();
	
	ПроверитьЗаполнениеРеквизита(Элементы.АдресПеренаправления, Отказ);
	ПроверитьЗаполнениеРеквизита(Элементы.ИдентификаторПриложения, Отказ);
	
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьЗаполнениеРеквизита(Элемент, Отказ)
	
	ИмяРеквизита = Элемент.Имя;
	
	Если Элемент.Видимость И Не ЗначениеЗаполнено(ЭтотОбъект[ИмяРеквизита]) Тогда
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Введите %1'"), Элемент.Заголовок);
			
		ОбщегоНазначенияКлиент.СообщитьПользователю(
			ТекстСообщения, , ИмяРеквизита, , Отказ);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ДоступнаАвторизацияПоКоду()
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	Возврат ЗначениеЗаполнено(НастройкиАвторизации)
		И (ЗначениеЗаполнено(НастройкиАвторизации.АдресРегистрацииУстройства) 
		Или ЗначениеЗаполнено(НастройкиАвторизации.АдресПеренаправленияВебКлиент));
	
КонецФункции

&НаКлиенте
Процедура НастроитьЭлементыТекущейСтраницыПриОткрытии()
	
	НастройкиАвторизации = НастройкиАвторизацииНаПочтовомСервере; // см. НастройкиАвторизацииНаПочтовомСервере
	
	Если ТолькоАвторизация Тогда
		Если Не ЗначениеЗаполнено(НастройкиАвторизации) Тогда
			Закрыть(НСтр("ru = 'Не найдены настройки авторизации для указанного адреса электронной почты.
			|Используйте авторизацию по логину и паролю.'"));
			Возврат;
		КонецЕсли;
		УстановитьТекстыПоясненийПоРегистрацииПриложения();
		Если Элементы.Страницы.ТекущаяСтраница = Элементы.Авторизация Тогда
			АвторизоватьсяНаПочтовомСервере();
		КонецЕсли;
	КонецЕсли;
	
	НастроитьЭлементыТекущейСтраницы();
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПояснения()
	
	ПоясненияПоОшибке = РаботаСПочтовымиСообщениямиСлужебный.ПоясненияПоОшибке(СообщенияОбОшибках, , Истина);
	
	ВозможныеПричины = РаботаСПочтовымиСообщениямиСлужебный.ФорматированныйСписок(ПоясненияПоОшибке.ВозможныеПричины);
	СпособыУстранения = РаботаСПочтовымиСообщениямиСлужебный.ФорматированныйСписок(ПоясненияПоОшибке.СпособыУстранения);
	
	Элементы.ДекорацияВозможныеПричины.Заголовок = ВозможныеПричины;
	Элементы.ДекорацияСпособыУстранения.Заголовок = СпособыУстранения;
	
КонецПроцедуры

&НаСервере
Процедура ПреобразоватьНастройкиИзPunycode()
	
	СерверВходящейПочты = РаботаСПочтовымиСообщениямиСлужебный.PunycodeВСтроку(СерверВходящейПочты);
	СерверИсходящейПочты = РаботаСПочтовымиСообщениямиСлужебный.PunycodeВСтроку(СерверИсходящейПочты);
	ИмяПользователяДляОтправкиПисем = РаботаСПочтовымиСообщениямиСлужебный.PunycodeВСтроку(ИмяПользователяДляОтправкиПисем);
	ИмяПользователяДляПолученияПисем = РаботаСПочтовымиСообщениямиСлужебный.PunycodeВСтроку(ИмяПользователяДляПолученияПисем);
	
КонецПроцедуры

#КонецОбласти
